package Vshift

import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec

class VShiftTest_hig extends AnyFlatSpec with ChiselScalatestTester {

  val Inst_SHL_vec2 = 0x4f215400  //    shift = 1  esize=32 num=2 Q=1
  val Inst_SHL_vec4 = 0x4f115400  //    shift = 1  esize=16 num=4 Q=1
  val Inst_SHL_vec8 = 0x4f095400  //    shift = 1  esize=8 num=8  Q=1

  val Inst_SLI_vec2 = 0x6f245400  //    shift = 4  esize=32 num=2 Q=1
  val Inst_SLI_vec4 = 0x6f125400  //    shift = 2  esize=16 num=4 Q=1
  val Inst_SLI_vec8 = 0x6f0a5400  //    shift = 2  esize=8 num=8  Q=1

  val Inst_SHLL_size = 0x6ee13800  //   shift = 64 esize=64 num=1
  val Inst_SHLL_size2 = 0x6ea13800 //   shift = 32 esize=32 num=2
  val Inst_SHLL_size4 = 0x6e613800 //   shift = 16 esize=16 num=4
  val Inst_SHLL_size8 = 0x6e213800 //   shift = 8 esize=8 num=8


  val Inst_SHRN_vec_low = 0x0f3f8400  //   shift = 1  esize=32 num=2
  val Inst_SHRN_vec_wb_hig = 0x4f3f8400   //   shift = 1  esize=64 num=2
  val Inst_SHRN_vec_wb_hig4 = 0x4f1f8400  //   shift = 1  esize=32 num=4
  val Inst_SHRN_vec_wb_hig8 = 0x4f0f8400  //   shift = 1  esize=32 num=4

  val inst_SRSRA_vec2_Q1 = 0x4f3f3400 //shift = 1 esize=32 num=2
  val inst_SRSRA_vec4_Q1 = 0x4f1f3400 //shift = 1 esize=16 num=4
  val inst_SRSRA_vec8_Q1 = 0x4f0f3400 //shift = 1 esize=8 num=8


  val Inst_SQRSHL_vec1_sign_sat_round_hig = 0x4ee05c00
  val Inst_SQRSHL_vec2_sign_sat_round_hig = 0x4ea05c00
  val Inst_SQRSHL_vec4_sign_sat_round_hig = 0x4e605c00
  val Inst_SQRSHL_vec8_sign_sat_round_hig = 0x4e205c00

  "VShiftTop" should "work" in {
    test(new VShiftTop(2)).withAnnotations(Seq(WriteVcdAnnotation)) { dut =>


      setInputPattern("SHL_vec2", Inst_SHL_vec2, "h0000_0002_8000_0002".U, "h0000_0000_0000_0000".U, "h0000_0004_0000_0004".U,0.U)
      setInputPattern("SHL_vec4", Inst_SHL_vec4, "h0002_8002_8002_8002".U, "h0000_0000_0000_0000".U, "h0004_0004_0004_0004".U,0.U)
      setInputPattern("SHL_vec8", Inst_SHL_vec8, "h0282_0282_0282_0282".U, "h0000_0000_0000_0000".U, "h0404_0404_0404_0404".U,0.U)


      setInputPattern("SLI_vec2", Inst_SLI_vec2, "h7777_7777_7777_7777".U, "h0000_0000_0000_0000".U, "h7777_7779_7777_7779".U,0.U)
      setInputPattern("SLI_vec4", Inst_SLI_vec4, "h7777_7777_7777_7777".U, "h0000_0000_0000_0000".U, "hdddd_dddd_dddd_dddd".U,0.U)
      setInputPattern("SLI_vec8", Inst_SLI_vec8, "h7777_7777_7777_7777".U, "h0000_0000_0000_0000".U, "hdddd_dddd_dddd_dddd".U,0.U)


      setInputPattern("SHLL_size", Inst_SHLL_size, "h7777_7777_7777_7777".U, "h0000_0000_0000_0000".U, "h7777_7777_7777_7777".U,0.U)
      setInputPattern("SHLL_size2", Inst_SHLL_size2, "h7777_7777_7777_7777".U, "h0000_0000_0000_0000".U, "h7777_7777_0000_0000".U,0.U)
      setInputPattern("SHLL_size4", Inst_SHLL_size4, "h7777_7777_7777_7777".U, "h0000_0000_0000_0000".U, "h7777_0000_7777_0000".U,0.U)
      setInputPattern("SHLL_size8", Inst_SHLL_size8, "h7777_7777_7777_7777".U, "h0000_0000_0000_0000".U, "h7700_7700_7700_7700".U,0.U)


      setInputPattern("SHRN_vec_hig", Inst_SHRN_vec_wb_hig, "h8888_8888_4444_4444".U, "h0000_0000_0000_0000".U, "h2222_2222_0000_0000".U,0.U)
      setInputPattern("SHRN_vec_hig4", Inst_SHRN_vec_wb_hig4, "h8888_8888_4444_4444".U, "h0000_0000_0000_0000".U, "h4444_2222_0000_0000".U,0.U)
      setInputPattern("SHRN_vec_hig8", Inst_SHRN_vec_wb_hig8, "h2222_8888_4444_2222".U, "h0000_0000_0000_0000".U, "h1144_2211_0000_0000".U,0.U)


      setInputPattern("SRSRA_vec2_Q1_hig", inst_SRSRA_vec2_Q1, "h2444_4444_f044_4444".U, "h8888_8888_8288_8888".U, "h9aaa_aaaa_7aaa_aaaa".U,0.U)
      setInputPattern("SRSRA_vec4_Q1_low", inst_SRSRA_vec4_Q1, "h4441_4441_4441_4441".U, "h8888_8888_8888_8888".U, "haaa8_aaa8_aaa8_aaa8".U,0.U)
      setInputPattern("SRSRA_vec8_Q1_low", inst_SRSRA_vec8_Q1, "h4141_4141_4141_4141".U, "h8888_8888_8888_8888".U, "ha8a8_a8a8_a8a8_a8a8".U,0.U)


      setInputPattern("Inst_SQRSHL_vec1_sign_sat_round_hig", Inst_SQRSHL_vec1_sign_sat_round_hig, "h1111_1111_1111_1111".U, "h0000_0000_0000_0001".U, "h2222_2222_2222_2222".U,0.U)
      setInputPattern("Inst_SQRSHL_vec2_sign_sat_round_hig", Inst_SQRSHL_vec2_sign_sat_round_hig, "h0000_0005_0000_0005".U, "h0000_0001_ffff_ffff".U, "h0000_000a_0000_0003".U,0.U)
      setInputPattern("Inst_SQRSHL_vec4_sign_sat_round_hig", Inst_SQRSHL_vec4_sign_sat_round_hig, "h0005_0005_0005_0005".U, "hffff_0001_ffff_0001".U, "h0003_000a_0003_000a".U,0.U)
      setInputPattern("Inst_SQRSHL_vec8_sign_sat_round_hig", Inst_SQRSHL_vec8_sign_sat_round_hig, "h0505_0505_0505_0505".U, "hff01_ff01_ff01_ff01".U, "h030a_030a_030a_030a".U,0.U)







      def setInputPattern(instName: String ,inst:Int, op1:UInt, op2: UInt, dst:UInt, sat:UInt): Unit={
        dut.io.inst.poke((s"b"+inst.toBinaryString).asUInt(32.W))
        dut.io.srcData.oprand1_hig.poke(op1)
        dut.io.srcData.oprand2_hig.poke(op2)
        dut.io.dstData.poke("h9999_9999_9999_9999".U)
        dut.clock.step(1)

        dut.io.Vd_hig.expect(dst)
        dut.io.FPSR_QC.expect(sat)
        println(s"${instName} PASS")

      }


    }
  }
}




